/*
 * Copyright (C) 2012 Jonathan St-Michel <jonathan@abiwebz.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.abiwebz.platform.util.icons;

import java.awt.Dimension;
import java.util.ArrayList;
import java.util.ListIterator;
import org.abiwebz.platform.util.ModuleLoader;
import org.pushingpixels.flamingo.api.common.icon.ImageWrapperResizableIcon;
import org.pushingpixels.flamingo.api.common.icon.ResizableIcon;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 *
 * @author stmicj01
 */
public class Theme {
    /********* SINGLETON *****************************************************/
    protected static ArrayList<Theme> singletonInstances = new ArrayList<Theme> ();

    /**
     * Retourner une copie de l'application pour récupérer les informations
     * répertoriées au démarrage de celle-ci.
     * 
     * @return Une copie de l'application
     */
    public static Theme getInstance(String theme, String path) {
        Theme temp = null;
        boolean found = false;
        ListIterator<Theme> it = singletonInstances.listIterator();
        while(it.hasNext() && !found){
            temp = it.next();
            if(temp.getName().equals(theme)){
                found = true;
            }
        }
        if(found)
            return temp;
        else
            return newInstance(theme, path);
    }

    /**
     * Retourner une copie de l'application pour récupérer les informations
     * répertoriées au démarrage de celle-ci.
     * 
     * @return Une copie de l'application
     */
    public static Theme getInstance(String theme) {
        Theme temp = null;
        boolean found = false;
        ListIterator<Theme> it = singletonInstances.listIterator();
        while(it.hasNext() && !found){
            temp = it.next();
            if(temp.getName().equals(theme)){
                found = true;
            }
        }
        if(found)
            return temp;
        else
            return newInstance(theme, "");
    }
    
    /**
     * Créer selon la technique du "singleton" l'instance de la classe 
     * Application qui pourra être récupérée de n'importe où.
     * 
     * @return Une copie de la nouvelle application
     */
    private static Theme newInstance(String theme, String path) {
        Theme temp = new Theme(theme, path);
        singletonInstances.add(temp);
        return temp;
    }
    
    public static ResizableIcon getIconAsResizable(String resource, Dimension size) {
        return ImageWrapperResizableIcon.getIcon(ModuleLoader.getInstance().getResource(resource), size);
    }

    public static void buildFromXml(Element root){
        Node node;
        Element e;
        
        NodeList icons = root.getElementsByTagName("icons");
        for (int i = 0; i < icons.getLength(); i++) {
            node = icons.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE) {
                e = ((Element) node);
                
                Node theme;
                Element etheme;
                Theme curTheme;
                NodeList themes = e.getElementsByTagName("theme");
                for (int j = 0; j < themes.getLength(); j++) {
                    theme = themes.item(j);
                    if(theme.getNodeType() == Node.ELEMENT_NODE){
                        etheme = ((Element) theme);
                        curTheme = Theme.getInstance(etheme.getAttribute("name"), etheme.getAttribute("path"));
                        if(curTheme != null){
                            
                            curTheme.registerIconsFromXml(etheme);
                            
                        }
                    }
                }
            }
        }
    }
    
    /*************************************************************************/
    
    private String name;
    private String path;
    private ArrayList<IconRef> icons;
    
    public Theme(String name, String path) {
        this.name = name;
        this.path = path.equals("") ? "" : path.concat("/");
        this.icons = new ArrayList<IconRef>();
    }

    public String getName() {
        return name;
    }
    
    public void registerIconsFromXml(Element root){
        Node node;
        Element e;
        
        NodeList iconlist = root.getElementsByTagName("icon");
        for (int i = 0; i < iconlist.getLength(); i++) {
            node = iconlist.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE) {
                e = ((Element) node);
                registerIcon(e.getAttribute("name"), e.getAttribute("file"));
            }
        }
    }
    
    public void registerIcon(String name, String file){
        IconRef ref = new IconRef(name, file);
        //Vérifier si la référence existe déjà
        ListIterator<IconRef> it = this.icons.listIterator();
        IconRef temp;
        boolean found = false;
        while(it.hasNext() && !found){
            temp = it.next();
            if(temp.getName().equals(name)){
                found = true;
            }
        }
        if(!found){
            this.icons.add(ref);
        }
    }
    
    public ResizableIcon getIconAsResizable(String resource) {
        return getIconAsResizable(resource, 48);
    }
    
    public ResizableIcon getIconAsResizable(String resource, int size) {
        String res;
        res = findIcon(resource);
        if(res != null){
            return getIconAsResizable(res, new Dimension(size, size));
        }
        else{
            return getIconAsResizable(resource, new Dimension(size, size));
        }
    }
    
    private String findIcon(String name){
        ListIterator<IconRef> it = this.icons.listIterator();
        IconRef temp = null;
        boolean found = false;
        while(it.hasNext() && !found){
            temp = it.next();
            if(temp.getName().equals(name)){
                found = true;
            }
        }
        if(found && temp != null){
            return temp.getFile();
        }
        else{  //Rechercher l'icône avec le path par défault
            String resource = this.path + name + ".png";
            if (ModuleLoader.getInstance().getResource(resource) != null)  {
                return resource;
            }
        }
        return null;
    }
    
    private class IconRef {
        private final String file;
        private final String name;

        public IconRef(String name, String file) {
            this.name = name;
            this.file = file;
        }

        public String getFile() {
            return file;
        }

        public String getName() {
            return name;
        }
        
    }
    
}
